const easeInOutQuad = (t, b, c, d) => {
  t /= d / 2;
  if (t < 1) {
    // eslint-disable-next-line no-mixed-operators
    return c / 2 * t * t + b;
  }
  t--;
  // eslint-disable-next-line no-mixed-operators
  return -c / 2 * (t * (t - 2) - 1) + b;
};

// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
// eslint-disable-next-line func-names
const requestAnimFrame = (function () {
  const w:any = window;
  return w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); };
}());
/**
 * Because it's so fucking difficult to detect the scrolling element, just move them all
 * @param {number} amount
 * @param element
 */
function move(amount:number, element) {
  element.scrollTop = amount;
}

function Element() {
  return document.documentElement || document.body.parentNode || document.body;
}

/**
 * @param {number} to 离顶部高度
 * @param {number} duration
 * @param {Function} callback
 * @param element 滚动父元素  设置属性为 scroll-y: scroll  overflow: hidden
 * scrollTop 滚动条的位置  offsettop为当前元素离顶部(scrollTOP=0)的距离
 */
export function scrollTo(to, duration, callback, element = Element()) {
  const start = element.scrollTop;
  const change = to - start;
  const increment = 20;
  let currentTime = 0;
  duration = (typeof (duration) === 'undefined') ? 500 : duration;
  const animateScroll = () => {
    // increment the time
    currentTime += increment;
    // find the value with the quadratic in-out easing function
    const val = easeInOutQuad(currentTime, start, change, duration);
    // move 不停的调用 animateScroll()即改动scrollTop的值来达到滚动
    move(val, element);
    // do the animation unless its over
    if (currentTime < duration) {
      requestAnimFrame(animateScroll);
    } else if (callback && typeof (callback) === 'function') {
      // the animation is done so lets callback
      callback();
    }
  };
  animateScroll();
}
